package com.ikas.ai.server.module.equipment.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ikas.ai.server.error.BusinessException;
import com.ikas.ai.server.module.equipment.dao.EquipmentDAO;
import com.ikas.ai.server.module.equipment.model.dto.EquipmentAddDTO;
import com.ikas.ai.server.module.equipment.model.dto.EquipmentUpdateDTO;
import com.ikas.ai.server.module.equipment.model.po.Equipment;
import com.ikas.ai.utils.CollectionUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 设备资产管理
 *
 * @author tang.xuandong
 * @version 1.0.0
 * @date 2023/2/1 10:41
 */
@Service
public class EquipmentService extends ServiceImpl<EquipmentDAO, Equipment> {

    @Autowired
    private EquipmentDAO equipmentDAO;

    /**
     * 分页查询
     *
     * @param equipmentCode 设备编码
     * @param equipmentName 设备名称
     * @param systemNo      系统编号
     * @return list
     */
    public List<Equipment> pageQueryEquipment(String equipmentCode, String equipmentName, String systemNo) {
        LambdaQueryChainWrapper<Equipment> lambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(equipmentDAO);
        return lambdaQueryChainWrapper
                .like(StringUtils.isNotBlank(equipmentCode), Equipment::getEquipmentCode, equipmentCode)
                .like(StringUtils.isNotBlank(equipmentName), Equipment::getEquipmentName, equipmentName)
                .eq(StringUtils.isNotBlank(systemNo), Equipment::getSystemNo, systemNo)
                .orderByDesc(Equipment::getId)
                .list();
    }

    /**
     * 获取所有设备资产信息
     *
     * @return list
     */
    public List<Equipment> getEquipments(String systemNo) {
        LambdaQueryChainWrapper<Equipment> lambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(equipmentDAO);
        return lambdaQueryChainWrapper
                .like(StringUtils.isNotBlank(systemNo), Equipment::getSystemNo, systemNo)
                .list();
    }


    /**
     * 查询所有设备ID和编号
     *
     * @return list
     */
    public List<Map<String, Object>> getAllEquipmentIdAndCode() {
        return equipmentDAO.getAllEquipmentIdAndCode();
    }

    /**
     * 查询所有设备编号
     *
     * @return list
     */
    public List<String> getAllEquipmentCode(String systemNo) {
        LambdaQueryChainWrapper<Equipment> lambdaQueryChainWrapper = new LambdaQueryChainWrapper<>(equipmentDAO);
        return lambdaQueryChainWrapper
                .like(StringUtils.isNotBlank(systemNo), Equipment::getSystemNo, systemNo)
                .list().stream().map(Equipment::getEquipmentCode).collect(Collectors.toList());
    }

    /**
     * 获取设备信息，通过设备编码
     *
     * @param equipmentCode 设备编码
     * @return list
     */
    public Equipment getEquipmentByCode(String equipmentCode) {
        LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Equipment::getEquipmentCode, equipmentCode);
        List<Equipment> list = equipmentDAO.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 添加设备
     *
     * @param equipmentAddDTO
     * @return row
     */
    public int addEquipment(EquipmentAddDTO equipmentAddDTO, Long userId) {
        String equipmentCode = equipmentAddDTO.getEquipmentCode();
        String equipmentName = equipmentAddDTO.getEquipmentName();
        String systemNo = equipmentAddDTO.getSystemNo();
        if (StringUtils.isBlank(equipmentCode)
                || StringUtils.isBlank(equipmentName)
                || StringUtils.isBlank(systemNo)) {
            throw new BusinessException("设备编码、设备名称、系统编号不能为空");
        }
        // equipmentCode需要唯一
        if (getEquipmentByCodeAndSystemId(equipmentCode, equipmentAddDTO.getSystemId()) != null) {
            throw new BusinessException("该设备编码已经存在!");
        }
        Equipment equipment = new Equipment();
        BeanUtils.copyProperties(equipmentAddDTO, equipment);
        equipment.setCreateTime(new Date());
        equipment.setUpdateTime(new Date());
        equipment.setCreator(userId);
        equipment.setUpdater(userId);
        return equipmentDAO.insert(equipment);
    }

    private Equipment getEquipmentByCodeAndSystemId(String equipmentCode, Long systemId) {
        LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Equipment::getEquipmentCode, equipmentCode);
        queryWrapper.eq(Equipment::getSystemId, systemId);
        List<Equipment> list = equipmentDAO.selectList(queryWrapper);
        if (CollectionUtil.isEmpty(list)) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 更新设备
     *
     * @param param Equipment
     * @return row
     */
    public int updateEquipment(EquipmentUpdateDTO param, Long userId) {
        Long id = param.getId();
        String equipmentCode = param.getEquipmentCode();
        String equipmentName = param.getEquipmentName();
        String systemNo = param.getSystemNo();
        if (id == null
                || StringUtils.isBlank(equipmentCode)
                || StringUtils.isBlank(equipmentName)
                || StringUtils.isBlank(systemNo)) {
            throw new BusinessException("id、设备编码、设备名称、系统编号不能为空");
        }
        // equipmentCode需要唯一
        Equipment updateEquipment = equipmentDAO.selectById(id);
        Equipment equipment = getEquipmentByCodeAndSystemId(equipmentCode, param.getSystemId());
        if (equipment != null) {
            if (equipment.getId().intValue() != id && equipment.getEquipmentCode().equalsIgnoreCase(equipmentCode)) {
                throw new BusinessException("该设备编码已经存在!");
            }
        }
        BeanUtils.copyProperties(param, updateEquipment);
        updateEquipment.setUpdateTime(new Date());
        updateEquipment.setUpdater(userId);
        return equipmentDAO.updateById(updateEquipment);
    }

    /**
     * 删除信息
     *
     * @param ids list
     */
    public int deleteEquipment(List<Long> ids) {
        if (CollectionUtils.isNotEmpty(ids)) {
            List<Equipment> equipments = equipmentDAO.selectBatchIds(ids);
            if (CollectionUtils.isNotEmpty(equipments)) {
                return equipmentDAO.deleteBatchIds(ids);
            }
        }
        return 0;
    }

    public void batchAddEquipment(List<EquipmentAddDTO> equipmentAddDTOs, Long userId) {
        Map<String, Long> map = equipmentAddDTOs.stream().collect(Collectors.groupingBy(EquipmentAddDTO::getEquipmentCode, Collectors.counting()));
        List<String> countList = map.keySet().stream().filter(key -> map.get(key) > 1).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(countList)) {
            throw new BusinessException("设备编号不能重复！");
        }
        //删除该系统所有设备
        if (CollectionUtils.isNotEmpty(equipmentAddDTOs)) {
            Long systemId = equipmentAddDTOs.get(0).getSystemId();
            List<Long> ids = getEquipmentsBySystem(systemId).stream().map(Equipment::getId).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(ids)) {
                deleteEquipment(ids);
            }
        }
        equipmentAddDTOs.forEach(e -> addEquipment(e, userId));
    }

    public void batchUpdateEquipment(List<EquipmentUpdateDTO> equipmentUpdateDTOS, Long userId) {
        equipmentUpdateDTOS.forEach(e -> {
            if (Objects.nonNull(e.getId())) {
                updateEquipment(e, userId);
            } else {
                EquipmentAddDTO equipmentAddDTO = new EquipmentAddDTO();
                BeanUtils.copyProperties(e, equipmentAddDTO);
                addEquipment(equipmentAddDTO, userId);
            }
        });
    }

    public List<Equipment> getEquipmentsBySystem(Long systemId) {
        LambdaQueryChainWrapper<Equipment> wrapper = new LambdaQueryChainWrapper<>(equipmentDAO);
        return wrapper.eq(Equipment::getSystemId, systemId).list();
    }
}
